package com.cooldatasoft.taskManager.component;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;

import com.cooldatasoft.domain.model.Document;
import com.cooldatasoft.domain.model.DocumentType;
import com.cooldatasoft.domain.model.Project;
import com.cooldatasoft.domain.service.DocumentService;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Item;
import com.vaadin.data.Validator.EmptyValueException;
import com.vaadin.data.util.BeanItem;
import com.vaadin.ui.AbsoluteLayout;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.NativeButton;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

@SuppressWarnings("serial")
@Configurable(preConstruction = true)
public class DocumentationView extends CustomComponent {

	@AutoGenerated
	private AbsoluteLayout mainLayout;

	@AutoGenerated
	private VerticalLayout verticalLayout_3;

	@AutoGenerated
	private HorizontalLayout horizontalLayout_1;

	@AutoGenerated
	private NativeButton submitButton;

	@Autowired
	private DocumentService ducumentService;
	
	private Project myCurrentProject;
	private Document myDocument;
	
	private static final String DOUBLE_FIELD_WIDTH = "30em";
	
	private String[] yearValues = new String[]{"1.Bc", "2.Bc", "3.Bc", "1.Ing", "2.Ing"};
	
	private static final Logger logger = Logger.getLogger(DocumentationView.class);
	private BeanItem<Document> documentItem;
	private Form documentForm;

	
	public DocumentationView(Project project) {
		this.myCurrentProject = project;
	
		ensureDocument();
		myDocument = ducumentService.getByProjectAndType(myCurrentProject, DocumentType.MAIN);
		documentItem = new BeanItem<Document>(myDocument);
		
		
		buildMainLayout();
		setCompositionRoot(mainLayout);
		
		customizeSubmitButton();		
		
	}
	
	private void customizeSubmitButton() {
		submitButton.addListener(new Button.ClickListener() {
			
			@Override
			public void buttonClick(ClickEvent event) {
				try {
					documentForm.commit();					
					ducumentService.updateDocument(myDocument);
					savePartialDocumentation();
					
				} catch (EmptyValueException e) {
					logger.debug("ERROR > " + e.getMessage());
				}
			}
		});
	}
	
	private void savePartialDocumentation() {
		List<DocumentType> types = new ArrayList<DocumentType>();
		types.add(DocumentType.SYSTEM_GUIDE);
		types.add(DocumentType.USER_GUIDE);
		
		for(DocumentType type : types) {
			Document doc = ducumentService.getByProjectAndType(myCurrentProject, type);
			doc.setUniversity(myDocument.getUniversity());
			doc.setFaculty(myDocument.getFaculty());
			doc.setDepartment(myDocument.getDepartment());
			doc.setInstructor(myDocument.getInstructor());
			doc.setLecturer(myDocument.getLecturer());
			doc.setYear(myDocument.getYear());
			
			ducumentService.updateDocument(doc);
		}		
	}
	
	private void ensureDocument() {
		if (myDocument == null) {
			myDocument = new Document();
			myDocument.setProject(myCurrentProject);
			myDocument.setType(DocumentType.MAIN);
			myDocument.setId(ducumentService.insertDocument(myDocument));
			myDocument.setYear(yearValues[0]);
		}
	}
	
	public Form createForm() {
		documentForm = new Form();
		documentForm.setWidth("-1px");
		documentForm.setCaption("Documentation details");
		documentForm.setWriteThrough(false);
		documentForm.setInvalidCommitted(false);
		
		documentForm.setFormFieldFactory(new DocumentFieldFactory());
		documentForm.setItemDataSource(documentItem);
		
		documentForm.setVisibleItemProperties(new String[] {
				"university",
				"faculty",
				"department",
				"lecturer",
				"instructor",
				"year"				
		});
		return documentForm;	
	}
	
	 
	
	private class DocumentFieldFactory extends DefaultFieldFactory  {
		
		ComboBox studyYear = new ComboBox("Year of study");
		
		public DocumentFieldFactory() {			
		}
		
		@Override
		public Field createField(Item item, Object propertyId, Component uiContext) {
			Field f;
			
			if("year".equals(propertyId)) {
				f = createComboBoxField(propertyId);
			} else {
				f = super.createField(item, propertyId, uiContext);
			}			

			if("university".equals(propertyId)) {
				TextField tf = (TextField) f;
				tf.setCaption("University");
				tf.setImmediate(true);
				tf.setWidth(DOUBLE_FIELD_WIDTH);
				tf.setHeight("-1px");
				tf.setRequired(true);
				tf.setNullRepresentation("");
				tf.setRequiredError("Please enter an university name!");
				
			} else if("faculty".equals(propertyId)) {
				TextField tf = (TextField) f;
				tf.setCaption("Faculty");
				tf.setImmediate(true);
				tf.setWidth(DOUBLE_FIELD_WIDTH);
				tf.setHeight("-1px");
				tf.setRequired(true);
				tf.setNullRepresentation("");
				tf.setRequiredError("Please enter a name of faculty!");
				
			} else if("department".equals(propertyId)) {
				TextField tf = (TextField) f;
				tf.setCaption("Department");
				tf.setImmediate(true);
				tf.setWidth(DOUBLE_FIELD_WIDTH);
				tf.setHeight("-1px");
				tf.setRequired(true);
				tf.setNullRepresentation("");
				tf.setRequiredError("Please enter a name of department!");
				
			} else if("lecturer".equals(propertyId)) {
				TextField tf = (TextField) f;
				tf.setCaption("Lecturer");
				tf.setImmediate(true);
				tf.setWidth(DOUBLE_FIELD_WIDTH);
				tf.setHeight("-1px");
				tf.setRequired(true);
				tf.setNullRepresentation("");
				tf.setRequiredError("Please enter a name of lecturer!");
				
			} else if("instructor".equals(propertyId)) {
				TextField tf = (TextField) f;
				tf.setCaption("Instructor");
				tf.setImmediate(true);
				tf.setWidth(DOUBLE_FIELD_WIDTH);
				tf.setHeight("-1px");
				tf.setRequired(true);
				tf.setNullRepresentation("");
				tf.setRequiredError("Please enter a name of instructor!");
				
			} else if("year".equals(propertyId)) {
				studyYear = (ComboBox) f;
				studyYear.setRequired(true);
				studyYear.setImmediate(true);
				studyYear.setRequiredError("Please select year of study!");
				studyYear.setWidth(DOUBLE_FIELD_WIDTH);
				studyYear.setCaption("Year of study");
				studyYear.setNullSelectionAllowed(false);
				for(String type : yearValues) {
					studyYear.addItem(type);
				}
			}
			return f;			
		}
		
		private ComboBox createComboBoxField(Object propertyId) {
			ComboBox cb = new ComboBox();
			return cb;
		}
	}

	@AutoGenerated
	private AbsoluteLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new AbsoluteLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("100%");
		mainLayout.setMargin(true);
		
		// top-level component properties
		setWidth("100.0%");
		setHeight("100.0%");
		
		// verticalLayout_3
		verticalLayout_3 = buildVerticalLayout_3();
		mainLayout.addComponent(verticalLayout_3);
		
		return mainLayout;
	}

	@AutoGenerated
	private VerticalLayout buildVerticalLayout_3() {
		// common part: create layout
		verticalLayout_3 = new VerticalLayout();
		verticalLayout_3.setImmediate(true);
		verticalLayout_3.setWidth("100.0%");
		verticalLayout_3.setHeight("-1px");
		verticalLayout_3.setMargin(true);
		verticalLayout_3.setSpacing(true);
		
		verticalLayout_3.addComponent(createForm());
		verticalLayout_3.setComponentAlignment(documentForm, Alignment.MIDDLE_LEFT);
		
		// horizontalLayout_1
		horizontalLayout_1 = buildHorizontalLayout_1();
		verticalLayout_3.addComponent(horizontalLayout_1);
		verticalLayout_3.setExpandRatio(horizontalLayout_1, 1.0f);
		
		return verticalLayout_3;
	}

	@AutoGenerated
	private HorizontalLayout buildHorizontalLayout_1() {
		// common part: create layout
		horizontalLayout_1 = new HorizontalLayout();
		horizontalLayout_1.setImmediate(false);
		horizontalLayout_1.setWidth("-1px");
		horizontalLayout_1.setHeight("-1px");
		horizontalLayout_1.setMargin(false);
		horizontalLayout_1.setSpacing(true);
		
		// submitButton
		submitButton = new NativeButton("Save data");
		submitButton.setImmediate(true);
		submitButton.setWidth("-1px");
		submitButton.setHeight("-1px");
		submitButton.setStyleName("defaultBtn");
		horizontalLayout_1.addComponent(submitButton);
		
		return horizontalLayout_1;
	}
}
